﻿using DHISInteroperability.Authentication;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;

namespace DHISInteroperability.SystemInformation
{
    public class DHIS2System
    {
        public const string SYSTEM_INFO_URL = "/api/system/info";
        public const string SYSTEM_CONTEXT_URL = "/api/system/context";
        public const string SYSTEM_PING_URL = "/api/system/ping";
        public const string DATA_VALUES_POSTING_URL = "/api/dataValueSets";

        public const string DATASET_METADATA = "/api/dataSets";

        /// <summary>
        /// Name of Authorization Header
        /// </summary>
        public const string AUTHORIZATION_HEADER = "Authorization";

        /// <summary>
        /// Default Content Type i.e. application/xml
        /// </summary>
        public const string DEFAULT_CONTENT_TYPE = "application/xml";

        private AuthorizationAgent authorizationAgent;
        private string baseUrl;
        private HttpStatusCode lastHttpStatusCode;
        private string lastRequestRespondBody;


        public DHIS2System(string baseUrl, AuthorizationAgent agent)
        {
            this.authorizationAgent = agent;
            this.baseUrl = baseUrl;
        }

        public context GetContext()
        {
            SendGetRequest(SYSTEM_INFO_URL);
            if (lastHttpStatusCode == HttpStatusCode.OK)
            {
                var serializer = new JavaScriptSerializer();
                context systemContext = serializer.Deserialize<context>(lastRequestRespondBody);
                return systemContext;
            }
            else return null;
        }

        public bool Ping()
        {
            SendGetRequest(SYSTEM_PING_URL);
            return (lastHttpStatusCode == HttpStatusCode.OK);
        }

        public info GetInfo()
        {
            SendGetRequest(SYSTEM_INFO_URL);
            if (lastHttpStatusCode == HttpStatusCode.OK)
            {
                var serializer = new JavaScriptSerializer();
                info systemInfo = serializer.Deserialize<info>(lastRequestRespondBody);
                return systemInfo;

                //DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(info));
                //using (MemoryStream stream = new MemoryStream())
                //{
                //    byte[] data = ASCIIEncoding.ASCII.GetBytes(lastRequestRespondBody.ToCharArray());
                //    stream.Write(data, 0, data.Length);
                //    info systemInfo = serializer.ReadObject(stream) as info;
                //    return systemInfo;
                //}
            }
            else return null;
        }

        private void SendGetRequest(string targetUrl)
        {
            if (baseUrl.EndsWith("/")) baseUrl = baseUrl.Substring(0, baseUrl.Length - 1);
            string requestingUrl = string.Format("{0}{1}", baseUrl, targetUrl);

            var httpRequest = WebRequest.Create(requestingUrl);
            httpRequest.Method = "GET";
            httpRequest.Headers[AUTHORIZATION_HEADER] = authorizationAgent.AuthorizationText;
            httpRequest.ContentType = DEFAULT_CONTENT_TYPE;
            httpRequest.ContentLength = 0;

            var httpResponse = (HttpWebResponse)httpRequest.GetResponse();
            string output = string.Empty;           
            
            var responseStream = httpResponse.GetResponseStream();
            Encoding encode = Encoding.GetEncoding("utf-8");
            StreamReader reader = new StreamReader(responseStream, encode);
            output = reader.ReadToEnd();

            lastHttpStatusCode = httpResponse.StatusCode;
            lastRequestRespondBody = output;
        }
    }
}
